/**
 * jQuery EasyUI 1.3.6
 * Copyright (c) CaoChuanXi personal All rights reserved.
 *
 * Licensed under the GPL or commercial licenses
 * To use it on other terms please contact author: 15075107120@139.com
 *
 * jQuery EasyUI webexcel Plugin Extensions 1.0 beta
 * jQuery EasyUI webexcel 插件扩展
 * jquery.webexcel.css
 * jquery.webexcel-cell.js
 * jquery.webexcel-col.js
 * jquery.webexcel-draw.js
 * jquery.webexcel-handler.js
 * jquery.webexcel-row.js
 * jquery.webexcel-tool.js
 * 作者: 曹传喜
 * 最近更新：2019-05-15
 * 邮箱：15075107120@139.com
 *
 * 所有的坐标计算均为相对于web-excel容器，窗口坐标需先转换为容器坐标
 *
 * 依赖项：
 *   1、easyui.css
 *   2、jquery.easyui.min.js
 *   3、icon-all.min.css
 *   4、jquery.tool.js v1.0 beta late
 *   5、jeasyui.extensions.js v1.0 beta late
 *   6、jeasyui.extensions.menu.js
 *   14、flexi-color-picker/themes.css
 *   15、flexi-color-picker/colorpicker.min.js
 *
 */
(function ($) {

    //创建基本的webexcel的页面元素
    function create(target) {
        var t = $(target).addClass("web-excel"), state = $.data(target, "webexcel"), opts = state.options;

        //初始化容器
        opts.container = $('<div class="excel-container"/>');
        t.append(opts.container);

        //测试框
        opts.testBox = $('<div/>').addClass("excel-test-box").hide();
        opts.container.append(opts.testBox);

        //左上角固定单元格
        opts.leftTopCanvas = $('<canvas/>');
        opts.leftTopCellDiv = $('<div/>').addClass("excel-left-top-cell").append(opts.leftTopCanvas);
        opts.container.append(opts.leftTopCellDiv);
        //头部索引行
        opts.indexRowCanvas = $('<canvas/>');
        opts.indexRowDiv = $('<div/>').addClass("excel-index-row").append(opts.indexRowCanvas);
        opts.container.append(opts.indexRowDiv);
        //左侧索引列
        opts.indexColCanvas = $('<canvas/>');
        opts.indexColDiv = $('<div/>').addClass("excel-index-col").append(opts.indexColCanvas);
        opts.container.append(opts.indexColDiv);
        //内容编辑区域
        opts.contentCanvas = $('<canvas/>');
        opts.contentDiv = $('<div/>').addClass("excel-content").append(opts.contentCanvas);
        opts.container.append(opts.contentDiv);

        //内容选择框
        opts.chooseBox = $('<div/>').addClass("excel-choose-box").hide();
        opts.container.append(opts.chooseBox);

        //列宽/行高选择框
        opts.tableResizeBox = $('<div/>').addClass("excel-table-resize-box").hide();
        opts.container.append(opts.tableResizeBox);

        //编辑框
        opts.editInput = $('<textarea/>').addClass("excel-edit-textarea").css({'resize': 'none'}).hide();
        opts.container.append(opts.editInput);

        //颜色选择器
        opts.colorPickerDiv = $('<div/>').addClass("color-picker").hide();
        opts.container.append(opts.colorPickerDiv);

        //加载自定义右键菜单
        if (opts.otherMenuItems.length > 0) {
            opts.contextMenuItems.push({
                text: "其他",
                name: "otherMenu",
                iconCls: "icon-standard-application",
                children: opts.otherMenuItems
            });
        }
        init(target);
    }

    //初始化webexcel页面
    function init(target) {
        var state = $.data(target, "webexcel"), opts = state.options;
        $.fn.webexcel.plus.tool(target);
        $.fn.webexcel.plus.draw(target);
        $.fn.webexcel.plus.row(target);
        $.fn.webexcel.plus.col(target);
        $.fn.webexcel.plus.cell(target);
        $.fn.webexcel.plus.handler(target);
        handlerScroll(target);
        listenEvent(target);
        initFunctionHandler(target);
        opts.doLoadData(target);
    }

    //处理滚动锁定
    function handlerScroll(target) {
        var state = $.data(target, "webexcel"), opts = state.options;
        opts.container.on('scroll', function () {
            // noinspection JSValidateTypes
            var scrollLeft = $(this).scrollLeft();
            // noinspection JSValidateTypes
            var scrollTop = $(this).scrollTop();
            opts.leftTopCellDiv.css({left: scrollLeft, top: scrollTop});
            opts.indexRowDiv.css({top: scrollTop});
            opts.indexColDiv.css({left: scrollLeft});
            opts.colorPickerDiv.hide();
            opts.scrollDot = {x: scrollLeft, y: scrollTop};
        });
    }

    //事件加载
    function initFunctionHandler(target) {
        var state = $.data(target, "webexcel"), opts = state.options;
        if ($.isFunction(opts.onSuccess)) {
            opts.onSuccess.call(target);
        }
    }

    //监听页面操作
    function listenEvent(target) {
        var state = $.data(target, "webexcel"), opts = state.options;
        if (!opts.enableEdit) {
            return;
        }

        opts.editInput.blur(function () {//监听编辑单元格时失去焦点事件
            //设置单元格内容
            opts.editInput.hide();
            var cell = opts.data.contentData[opts.editInput.attr('cell-id')];
            cell.text = opts.editInput.val();
            opts.clearCanvasCell(opts.contentContext, cell);
            opts.drawCanvasCell(opts.contentContext, cell);
        });
        opts.editInput.keyup(function () {//监听编辑单元格按键事件
            //动态修改编辑框长度
            opts.changeEditInputCss(state, opts);
        });
        opts.contentCanvas.dblclick(function () {//监听编辑单元格双击事件，启用编辑
            opts.chooseBox.hide();
            opts.editInput.val(opts.chooseFirstCell.text);
            opts.editInput.attr('cell-id', opts.chooseFirstCell.id);
            opts.changeEditInputCss(state, opts);
        });
        opts.contentCanvas.mousedown(function (e) {//监听表格区域鼠标点击事件
            opts.colorPickerDiv.hide();
            opts.isMouseDown = true;
            var dot = {x: e.clientX, y: e.clientY};
            dot = opts.getDotByContainer(dot);
            opts.mouseMove = opts.mouseDown = dot;
            if (e.button != 0 && opts.chooseBoxCss) {
                //如果右键区域在选择框内则重设选择框坐标
                var minDot = {x: opts.chooseBoxCss.left, y: opts.chooseBoxCss.top};
                var maxDot = {x: minDot.x + opts.chooseBoxCss.width, y: minDot.y + opts.chooseBoxCss.height};
                var borderSize = opts.cellDefault.borderSize;
                opts.mouseDown = opts.dotCalculate(opts.mouseDown, opts.scrollDot, 1);
                if (opts.mouseDown.x >= minDot.x && opts.mouseDown.x <= maxDot.x &&
                    opts.mouseDown.y >= minDot.y && opts.mouseDown.y <= maxDot.y) {
                    opts.mouseDown = {x: minDot.x + borderSize, y: minDot.y + borderSize};
                    opts.mouseMove = {x: maxDot.x - borderSize * 2, y: maxDot.y - borderSize * 2};
                    opts.mouseDown = opts.dotCalculate(opts.mouseDown, opts.scrollDot, 0);
                    opts.mouseMove = opts.dotCalculate(opts.mouseMove, opts.scrollDot, 0);
                }
            }
            opts.drawChooseBox(target);
        });
        opts.contentCanvas.mouseup(function () {//监听表格区域鼠标松开事件
            opts.isMouseDown = false;
        });
        opts.contentCanvas.mousemove(function (e) {//监听表格区域鼠标移动事件
            opts.mouseMove = opts.getDotByContainer({x: e.clientX, y: e.clientY});
            if (opts.isMouseDown) {
                opts.drawChooseBox(target);
            }
        });
        opts.contentCanvas.mouseout(function () {//监听表格区域鼠标移出事件
            opts.isMouseDown = false;
        });
        opts.contentCanvas.contextmenu(function (e) {//监听表格区域的右键事件
            e.preventDefault();
            $.easyui.showMenu({
                left: e.pageX,
                top: e.pageY,
                items: opts.contextMenuItems,
                onClick: function (item) {
                    opts.contentMenuHandler(item, e);
                }
            });
            opts.mouseMove = null;
        });
        $(document).keyup(function (e) {//监听表格区域按键事件
            opts.listenEditInputKeyUp(state, opts, e);
        }).mouseup(function (e) {
            //设置表格列宽
            if (opts.indexColResizeLock && opts.indexColResizeCell) {
                opts.settingIndexColResize(target, e);
            }
            //设置表格行高
            if (opts.indexRowResizeLock && opts.indexRowResizeCell) {
                opts.settingIndexRowResize(target, e);
            }
            opts.container.css({'cursor': 'default'});
            opts.indexRowResizeCell = null;
            opts.indexRowResizeLock = false;
            opts.indexColResizeCell = null;
            opts.indexColResizeLock = false;
        }).mousemove(function (e) {
            //设置表格列宽拖动动画
            if (opts.indexColResizeLock && opts.indexColResizeCell) {
                opts.showIndexColResize(target, e, false);
            }
            //设置表格行高拖动动画
            if (opts.indexRowResizeLock && opts.indexRowResizeCell) {
                opts.showIndexRowResize(target, e, false);
            }
        });
        $(opts.indexRowCanvas).mousedown(function (e) {//索引行的鼠标点击监听
            //初始化拉动调整列宽样式
            var dot = {x: e.clientX - opts.contentCanvasDot.x, y: e.clientY};
            dot = opts.dotCalculate(dot, opts.containerDot, 0);
            dot = opts.dotCalculate(dot, opts.scrollDot, 1);
            for (var key in opts.data.indexRowData) {
                var cell = opts.data.indexRowData[key];
                var bx = cell.x + cell.w - 1;
                var ex = cell.x + cell.w + 1;
                if (dot.x >= bx && dot.x <= ex) {
                    opts.indexColResizeCell = cell;
                }
            }
            if (opts.indexColResizeCell) {
                opts.container.css({'cursor': 'col-resize'});
                opts.showIndexColResize(target, e, true);
                opts.indexColResizeLock = true;
            } else {
                opts.container.css({'cursor': 'default'});
                opts.chooseWholeCol(target, dot);
            }
        }).mouseout(function () {//索引行的鼠标移出监听
            if (!opts.indexColResizeLock) {
                opts.container.css({'cursor': 'default'});
                opts.indexColResizeCell = null;
            }
        }).mousemove(function (e) {//索引行的鼠标移动监听
            if (!opts.indexColResizeLock) {
                if (opts.indexColResizeCell) {
                    opts.indexColResizeCell = null;
                } else {
                    //初始化拉动调整列宽样式
                    var dot = {x: e.clientX - opts.contentCanvasDot.x, y: e.clientY};
                    dot = opts.dotCalculate(dot, opts.containerDot, 0);
                    dot = opts.dotCalculate(dot, opts.scrollDot, 1);
                    for (var key in opts.data.indexRowData) {
                        var cell = opts.data.indexRowData[key];
                        var bx = cell.x + cell.w - 1;
                        var ex = cell.x + cell.w + 1;
                        if (dot.x >= bx && dot.x <= ex) {
                            opts.indexColResizeCell = cell;
                        }
                    }
                    if (opts.indexColResizeCell) {
                        opts.container.css({'cursor': 'col-resize'});
                    } else {
                        opts.container.css({'cursor': 'default'});
                    }
                }
            }
        }).contextmenu(function (e) {//索引行的右键监听
            e.preventDefault();
            var dot = {x: e.clientX - opts.contentCanvasDot.x, y: e.clientY};
            dot = opts.dotCalculate(dot, opts.containerDot, 0);
            dot = opts.dotCalculate(dot, opts.scrollDot, 1);
            opts.chooseWholeCol(target, dot);
            $.easyui.showMenu({
                left: e.pageX,
                top: e.pageY,
                items: opts.indexRowMenuItems,
                onClick: function (item) {
                    opts.colMenuHandler(item, e);
                }
            });
            opts.mouseMove = null;
        });
        $(opts.indexColCanvas).mousedown(function (e) {//索引列的鼠标点击监听
            //初始化拉动调整行高样式,去掉索引行高度
            var dot = {x: e.clientX, y: e.clientY - opts.contentCanvasDot.y};
            dot = opts.dotCalculate(dot, opts.containerDot, 0);
            dot = opts.dotCalculate(dot, opts.scrollDot, 1);
            for (var key in opts.data.indexColData) {
                var cell = opts.data.indexColData[key];
                var by = cell.y + cell.h - 1;
                var ey = cell.y + cell.h + 1;
                if (dot.y >= by && dot.y <= ey) {
                    opts.indexRowResizeCell = cell;
                }
            }
            if (opts.indexRowResizeCell) {
                opts.container.css({'cursor': 'row-resize'});
                opts.showIndexRowResize(target, e, true);
                opts.indexRowResizeLock = true;
            } else {
                opts.container.css({'cursor': 'default'});
                opts.chooseWholeRow(target, dot);
            }
        }).mouseout(function () {//索引列的鼠标移出监听
            if (!opts.indexRowResizeLock) {
                opts.container.css({'cursor': 'default'});
                opts.indexRowResizeCell = null;
            }
        }).mousemove(function (e) {//索引列的鼠标移动监听
            if (!opts.indexRowResizeLock) {
                if (opts.indexRowResizeCell) {
                    opts.indexRowResizeCell = null;
                } else {
                    //初始化拉动调整行高样式
                    var dot = {x: e.clientX, y: e.clientY - opts.contentCanvasDot.y};
                    dot = opts.dotCalculate(dot, opts.containerDot, 0);
                    dot = opts.dotCalculate(dot, opts.scrollDot, 1);
                    for (var key in opts.data.indexColData) {
                        var cell = opts.data.indexColData[key];
                        var by = cell.y + cell.h - 1;
                        var ey = cell.y + cell.h + 1;
                        if (dot.y >= by && dot.y <= ey) {
                            opts.indexRowResizeCell = cell;
                        }
                    }
                    if (opts.indexRowResizeCell) {
                        opts.container.css({'cursor': 'row-resize'});
                    } else {
                        opts.container.css({'cursor': 'default'});
                    }
                }
            }
        }).contextmenu(function (e) {//索引列的右键监听
            e.preventDefault();
            var dot = {x: e.clientX, y: e.clientY - opts.contentCanvasDot.y};
            dot = opts.dotCalculate(dot, opts.containerDot, 0);
            dot = opts.dotCalculate(dot, opts.scrollDot, 1);
            opts.chooseWholeRow(target, dot);
            $.easyui.showMenu({
                left: e.pageX,
                top: e.pageY,
                items: opts.indexColMenuItems,
                onClick: function (item) {
                    opts.rowMenuHandler(item, e);
                }
            });
            opts.mouseMove = null;
        });

    }

    $.fn.webexcel = function (options, param) {
        if (typeof options == "string") {
            var method = $.fn.webexcel.methods[options];
            if (method) {
                return method(this, param);
            } else {
                return this.webexcel("panel").panel(options, param);
            }
        }
        options = options || {};
        return this.each(function () {
            var state = $.data(this, "webexcel");
            if (state) {
                $.extend(true, state.options, options);
            } else {
                $.data(this, "webexcel", {options: $.extend(true, {}, $.fn.webexcel.defaults, $.fn.webexcel.parseOptions(this), options)});
                create(this);
            }
        });
    };

    $.fn.webexcel.parseOptions = function (target) {
        return $.extend(true, {}, $.parser.parseOptions(target, []));
    };

    //webexcel所有的默认属性初始化
    $.fn.webexcel.defaults = {
        width: 0,//webExcel的宽度，自适应调整
        height: 0,//webExcel的高度，自适应调整
        colCount: 50,//默认列数
        rowCount: 50,//默认行数
        colWidth: 100,//默认列宽
        rowHeight: 22,//默认行高
        indexColWidth: 40,//默认索引列列宽
        indexBgColor: "#e1eae4",//索引区域背景颜色
        indexBorderColor: "#808080",//索引区域边框颜色
        contentBorderColor: "#d3d3d3",//内容区域边框默认显示颜色
        setBorderColor: "#000000",//内容区域边框设置颜色
        chooseBorderColor: "#008000",//选择框边框颜色
        chooseBorderSize: 2,//选择框边框厚度，默认2px
        editBorderColor: "#0000ff",//选择框边框颜色
        editBorderSize: 2,//选择框边框厚度，默认2px
        resizeBorderColor: "#808080",//表格重置大小边框颜色
        enableEdit: true,//是否启用excel编辑功能，默认启用
        scrollDot: {x: 0, y: 0},//滚动条坐标
        data: {
            indexRowData: {},//索引行数据
            indexColData: {},//索引列数据
            contentData: {}//内容数据
        },
        cellDefault: {
            showCell: true,//是否显示单元格，默认显示
            id: '',//单元格ID
            padding: 4,//默认单元格内边距，默认4px
            bgColor: "#ffffffff",//单元格背景颜色，默认透明
            textColor: "#000000",//文本颜色
            lineHeight: 22, //文字的行高
            borderSize: 1,//cell，默认1px
            border: false,//是否有边框，为true时，上下左右边框设置无效
            borderLeft: false,//是否有左边框
            borderTop: false,//是否有上边框
            borderRight: false,//是否有右边框
            borderBottom: false,//是否有下边框
            bold: false,//字体加粗，默认不加粗
            fontSize: 12,//字体大小，默认12px
            font: "SimSun",//单元格字体，默认宋体（SimSun）
            text: '',//单元格文本内容
            /*
             *文本类型，默认文本：
             * 0-9：文本
             * 10-19：数值
             * 20-29：货币
             * 30-39：日期
             * 40-49：百分比
             * */
            textType: 0,
            /*
             *水平对齐，默认居左：
             * 1：靠左
             * 2：居中
             * 3：靠右
             * */
            hAlign: 1,
            /*
             *垂直对齐，默认居中：
             * 1：靠上
             * 2：居中
             * 3：靠下
             * */
            vAlign: 2
        },
        otherMenuItems: [],//其他自定义菜单
        indexColMenuItems: [{//索引列菜单
            text: "插入行",
            name: "insertRow",
            iconCls: "icon-standard-table-row-insert"
        }, {
            text: "添加行",
            name: "addRow",
            iconCls: "icon-standard-table-row-insert"
        }, {
            text: "删除行",
            name: "removeRow",
            iconCls: "icon-standard-table-row-delete"
        }],
        indexRowMenuItems: [{//索引行菜单
            text: "插入列",
            name: "insertCol",
            iconCls: "icon-standard-table-row-insert"
        }, {
            text: "添加列",
            name: "addCol",
            iconCls: "icon-standard-table-row-insert"
        }, {
            text: "删除列",
            name: "removeCol",
            iconCls: "icon-standard-table-row-delete"
        }],
        contextMenuItems: [{//内容区单元格菜单
            text: "合并单元格",
            name: "mergeCell",
            iconCls: "icon-standard-application-side-list"
        }, {
            text: "字体加粗",
            name: "textBold",
            iconCls: "icon-standard-text-bold"
        }, "-", {
            text: "对齐方式",
            iconCls: "icon-standard-text-align-justify",
            children: [{
                text: "水平居左",
                name: "hAlignLeft",
                children: '',
                iconCls: "icon-standard-text-align-left"
            }, {
                text: "水平居中",
                name: "hAlignCenter",
                iconCls: "icon-standard-text-align-center"
            }, {
                text: "水平居右",
                name: "hAlignRight",
                iconCls: "icon-standard-text-align-right"
            }, "-", {
                text: "垂直居上",
                name: "vAlignLeft",
                iconCls: "icon-standard-text-align-left"
            }, {
                text: "垂直居中",
                name: "vAlignCenter",
                iconCls: "icon-standard-text-align-center"
            }, {
                text: "垂直居下",
                name: "vAlignRight",
                iconCls: "icon-standard-text-align-right"
            }]
        }, {
            text: "边框样式",
            iconCls: "icon-standard-application",
            children: [{
                text: "无框线",
                name: "noBorder",
                children: '',
                iconCls: "icon-standard-table"
            }, {
                text: "所有框线",
                name: "allBorder",
                iconCls: "icon-standard-table"
            }, {
                text: "外框线",
                name: "outBorder",
                iconCls: "icon-standard-table"
            }, "-", {
                text: "上框线",
                name: "topBorder",
                iconCls: "icon-standard-table"
            }, {
                text: "下框线",
                name: "bottomBorder",
                iconCls: "icon-standard-table"
            }, {
                text: "左框线",
                name: "leftBorder",
                iconCls: "icon-standard-table"
            }, {
                text: "右框线",
                name: "rightBorder",
                iconCls: "icon-standard-table"
            }, "-", {
                text: "上下框线",
                name: "topBottomBorder",
                iconCls: "icon-standard-table"
            }, {
                text: "左右框线",
                name: "leftRightBorder",
                iconCls: "icon-standard-table"
            }]
        }, {
            text: "背景颜色",
            name: "bgColor",
            iconCls: "icon-standard-color-wheel"
        }, "-", {
            text: "导出",
            name: "exportExcel",
            iconCls: "icon-standard-page-excel"
        }, "-"],

        onSuccess: function (file) {//加载成功后的事件
        }
    };

    //定义webexcel支持的方法
    $.fn.webexcel.methods = {

        //获取webExcel的属性对象
        options: function (jq) {
            var state = $.data(jq[0], "webexcel");
            return state.options;
        },

        //获取webExcel的元素对象
        webexcel: function (jq) {
            return $.data(jq[0], "webexcel").webexcel;
        },

        //重置webExcel的页面布局-未实现
        resize: function (jq, param) {
        },

        //获取webExcel的全量数据
        getData: function (jq) {
            var state = $.data(jq[0], "webexcel"), opts = state.options;
            return opts.getData();
        },

        //获取webExcel的压缩数据
        getCompressData: function (jq) {
            var state = $.data(jq[0], "webexcel"), opts = state.options;
            return opts.getCompressData();
        },

        //加载webExcel数据
        loadData: function (jq, param) {
            var state = $.data(jq[0], "webexcel"), opts = state.options;
            return opts.doLoadData(jq[0], param);
        },

        //导出webExcel表格
        exportExcel: function (jq, param) {
            var state = $.data(jq[0], "webexcel"), opts = state.options;
            return opts.doExportExcel(param);
        }
    };

    //初始化处理函数空间
    $.fn.webexcel.plus = {};

    $.parser.plugins.push("webexcel");

})(jQuery);
